home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / bbs_util / bsrc_260.zip / SRC.ZIP / SCHED.C < prev    next >
C/C++ Source or Header  |  1996-03-23  |  15KB  |  545 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*              (C) Copyright 1987-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*           This module was originally written by Bob Hartman              */
  13. /*                                                                          */
  14. /*                     BinkleyTerm Scheduler Routines                       */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. /* Include this file before any other includes or defines! */
  45.  
  46. #include "includes.h"
  47.  
  48. /**************************************************************************/
  49. /*** This MUST be exactly 16 total bytes including the terminating null ***/
  50. /*** or the routines read_sched() and write_sched() must be changed!!!! ***/
  51. /**************************************************************************/
  52. static char *BinkSched = PRDCT_SHRT "Schedule 09";    /* Version of scheduler   */
  53.  
  54. void 
  55. find_event ()
  56. {
  57.     time_t long_time;
  58.     struct tm *tm;
  59.  
  60.     int cur_day;
  61.     int our_time;
  62.     int i;
  63.     char cmds[150];
  64.  
  65.     BINK_EVENT evt;
  66.  
  67.     /* Get the current time into a structure */
  68.  
  69.     (void) time (&long_time);
  70.     tm = localtime (&long_time);
  71.  
  72.     cur_day = 1 << tm->tm_wday;
  73.  
  74.     our_time = (tm->tm_hour % 24) * 60 + (tm->tm_min % 60);
  75.  
  76.     cur_event = -1;
  77.  
  78.     if (tm->tm_mday != hist.which_day)
  79.     {
  80.         write_stats ();
  81.         (void) memset (&hist, 0, sizeof (HISTORY));
  82.         start_hist = hist;
  83.         hist.which_day = tm->tm_mday;
  84.         if (un_attended && fullscreen)
  85.         {
  86.             do_today ();
  87.             sb_show ();
  88.         }
  89.     }
  90.  
  91.     /* Make the month 1-based instead of 0-based */
  92.     tm->tm_mon += 1;
  93.  
  94.     /* Go through the events from top to bottom */
  95.     for (i = 0; i < num_events; i++)
  96.     {
  97.         if (our_time >= e_ptrs[i].minute)
  98.         {
  99.             evt = e_ptrs[i];
  100.  
  101.             if ((cur_day & evt.days) &&
  102.                 ((!evt.day) || (evt.day == (char) tm->tm_mday)) &&
  103.                 ((!evt.month) || (evt.month == (char) tm->tm_mon)))
  104.             {
  105.                 if (((our_time - evt.minute) < evt.length) ||
  106.                     ((our_time == evt.minute) && (evt.length == 0)) ||
  107.                     ((evt.behavior & MAT_FORCED) && (evt.last_ran != (char) tm->tm_mday)))
  108.                 {
  109.                     /* Are we not supposed to force old events */
  110.                     if (((our_time - evt.minute) > evt.length) && (noforce))
  111.                     {
  112.                         e_ptrs[i].last_ran = (char) tm->tm_mday;
  113.                         continue;
  114.                     }
  115.  
  116.                     if (evt.last_ran != (char) tm->tm_mday)
  117.                     {
  118.                         cur_event = i;
  119.                         do_ready (MSG_TXT (M_READY_WAITING));
  120.                         status_line (MSG_TXT (M_STARTING_EVENT), i + 1);
  121.  
  122.                         if (!blank_on_key)
  123.                             screen_blank = 0;
  124.  
  125.                         more_mail = 1;
  126.  
  127.                         /* Mark that this one is running */
  128.                         e_ptrs[i].last_ran = (char) tm->tm_mday;
  129.  
  130.                         /*
  131.                             * Mark that we have not yet skipped it. After all, it just
  132.                             * started!
  133.                             */
  134.                         e_ptrs[i].behavior &= ~MAT_SKIP;
  135.  
  136.                         /* Write out the schedule */
  137.                         write_sched ();
  138.  
  139.                         /* Do this first ... if any $.. to kill, do it */
  140.                         if (e_ptrs[i].behavior & MAT_KILLBAD)
  141.                             kill_bad ();
  142.  
  143.  
  144.                         /* If we are supposed to exit, then do it */
  145.                         if (evt.errlevel[0])
  146.                         {
  147.                             if (errlvlshell[evt.errlevel[0] - 1] == NULL)
  148.                             {
  149.                                 status_line (MSG_TXT (M_EVENT_EXIT), evt.errlevel[0]);
  150.                                 screen_blank = 0;
  151.                                 errl_exit (evt.errlevel[0]);
  152.                             }
  153.                             else
  154.                             {
  155.                                 status_line (MSG_TXT (M_EVENT_SHELL), evt.errlevel[0]);
  156.                                 errl_shell (evt.errlevel[0]);
  157.                             }
  158.                         }
  159.                         else if (packer != NULL || cleanup != NULL)
  160.                         {
  161.                             if (!blank_on_key)
  162.                                 screen_blank = 0;
  163.                             status_line (MSG_TXT (M_CLEAN_PACK));
  164.                             mdm_init (modem_busy);
  165.                             exit_DTR ();
  166.                             screen_clear ();
  167.                             vfossil_cursor (1);
  168.                             if (cleanup != NULL)
  169.                             {
  170.                                 (void) strcpy (cmds, cleanup);
  171.                                 if (i >= 0)
  172.                                     (void) strcat (cmds, evt.cmd);
  173.                                 b_spawn (cmds);
  174.                             }
  175.                             if (packer != NULL)
  176.                             {
  177.                                 (void) strcpy (cmds, packer);
  178.                                 if (i >= 0)
  179.                                     (void) strcat (cmds, evt.cmd);
  180.                                 b_spawn (cmds);
  181.                             }
  182.                             if (fullscreen)
  183.                             {
  184.                                 screen_clear ();
  185.                                 sb_dirty ();
  186.                                 opening_banner ();
  187.                                 mailer_banner ();
  188.                             }
  189.                             RAISE_DTR ();
  190.                             mdm_init (modem_init);
  191.                             status_line (MSG_TXT (M_AFTER_CLEAN_PACK));
  192.                             waitfor_line = timerset ((unsigned int) 6000);
  193.                         }
  194.  
  195.                         cur_event = i;
  196.                         max_connects = evt.with_connect;
  197.                         max_noconnects = evt.no_connect;
  198.                         set_up_outbound ();
  199.                     }
  200.                     else
  201.                     {
  202.                         /* Don't do events that have been exited already */
  203.                         if (evt.behavior & MAT_SKIP)
  204.                             continue;
  205.                     }
  206.  
  207.                     cur_event = i;
  208.  
  209.                     if (evt.behavior & MAT_NOREQ)
  210.                     {
  211.                         matrix_mask &= ~TAKE_REQ;
  212.                         no_requests = 1;
  213.                     }
  214.                     else
  215.                     {
  216.                         matrix_mask |= TAKE_REQ;
  217.                         no_requests = 0;
  218.                     }
  219.  
  220.                     if (evt.behavior & MAT_NOOUTREQ)
  221.                     {
  222.                         requests_ok = 0;
  223.                     }
  224.                     else
  225.                     {
  226.                         requests_ok = 1;
  227.                     }
  228.  
  229.                     max_connects = evt.with_connect;
  230.                     max_noconnects = evt.no_connect;
  231.  
  232.                     break;
  233.                 }
  234.             }
  235.         }
  236.     }
  237. }
  238.  
  239. void 
  240. read_sched ()
  241. {
  242.     char temp1[80], temp2[80];
  243.     struct stat buffer1, buffer2;
  244.  
  245.     HFILE stream;
  246.     unsigned long got;
  247.  
  248.     (void) strcpy (temp1, BINKpath);
  249.     (void) strcpy (temp2, BINKpath);
  250.     (void) strcat (temp1, PRDCT_PRFX ".Scd");
  251.     (void) strcat (temp2, PRDCT_PRFX ".Evt");
  252.  
  253.     if (stat (temp1, &buffer1) == -1)
  254.     {
  255.         return;
  256.     }
  257.  
  258.     if (stat (temp2, &buffer2) == -1)
  259.     {
  260.         (void) strcpy (temp2, BINKpath);
  261.         (void) strcat (temp2, config_name);
  262.         if (stat (temp2, &buffer2) == -1)
  263.         {
  264.             return;
  265.         }
  266.     }
  267.  
  268.     if ((buffer1.st_atime < buffer2.st_atime) ||
  269.         (buffer1.st_size < sizeof (BINK_EVENT)))
  270.     {
  271.         return;
  272.     }
  273.  
  274.     if ((stream = (HFILE) open (temp1, O_RDONLY | O_BINARY)) == (HFILE) - 1)
  275.     {
  276.         return;
  277.     }
  278.  
  279.     temp1[0] = '\0';
  280.     (void) read (stream, temp1, 16);
  281.     if (strcmp (temp1, BinkSched) != 0)
  282.     {
  283.         (void) close (stream);
  284.         return;
  285.     }
  286.  
  287.     (void) read (stream, (char *) &hist, (int) sizeof (HISTORY));
  288.     start_hist = hist;
  289.  
  290.     /* Note, we do not use "got". Some platforms want it to be a long
  291.        and some want it to be a int. We don't care, so we make it a
  292.        long (see above) so there's enough room, then use a void * so
  293.        the compiler won't complain about an argument we don't even want */
  294.  
  295.     (void) _dos_read (stream, (char far *) e_ptrs,
  296.         (USHORT) (buffer1.st_size - 16 - sizeof (HISTORY)), (void *)&got);
  297.  
  298.     got_sched = 1;
  299.  
  300.     num_events = (int) ((buffer1.st_size - 16 - sizeof (HISTORY)) / sizeof (BINK_EVENT));
  301.  
  302.     (void) close (stream);
  303.     return;
  304. }
  305.  
  306. void 
  307. write_sched ()
  308. {
  309.     char temp1[80], temp2[80];
  310.     int i;
  311.     struct stat buffer1;
  312.     struct utimbuf times;
  313.     long t;
  314.  
  315.     HFILE stream;
  316.  
  317.     unsigned long got;
  318.  
  319.     /* Get the current time */
  320.     t = time (NULL);
  321.  
  322.     (void) strcpy (temp1, BINKpath);
  323.     (void) strcpy (temp2, BINKpath);
  324.     (void) strcat (temp1, PRDCT_PRFX ".Scd");
  325.     (void) strcat (temp2, PRDCT_PRFX ".Evt");
  326.  
  327.     /* Get the current stat for .Evt file */
  328.  
  329.     if (stat (temp2, &buffer1) == -1)
  330.     {
  331.         (void) strcpy (temp2, BINKpath);
  332.         (void) strcat (temp2, config_name);
  333.         if (stat (temp2, &buffer1) == -1)
  334.         {
  335.             return;
  336.         }
  337.     }
  338.  
  339.     /*
  340.     * If it is newer than current time, we have a problem and we must
  341.     * reset the file date - yucky, but it will probably work
  342.     */
  343.     if ((time_t) t < buffer1.st_atime)
  344.     {
  345.         times.UT_ACTIME = buffer1.st_atime;
  346.         times.modtime = buffer1.st_atime;
  347.         status_line (MSG_TXT (M_DATE_PROBLEM));
  348.     }
  349.     else
  350.     {
  351.         times.UT_ACTIME = t;
  352.         times.modtime = t;
  353.     }
  354.  
  355.     if ((stream = (HFILE) open (temp1, O_CREAT | O_RDWR | O_BINARY, S_IREAD | S_IWRITE)) == (HFILE) - 1)
  356.     {
  357.         return;
  358.     }
  359.  
  360.     (void) write (stream, BinkSched, 16);
  361.     (void) write (stream, (char *) &hist, (int) sizeof (HISTORY));
  362.  
  363.     for (i = 0; i < num_events; i++)
  364.     {
  365.         /* If it is skipped, but not dynamic, reset it */
  366.         if ((e_ptrs[i].behavior & MAT_SKIP) &&
  367.             (!(e_ptrs[i].behavior & MAT_DYNAM)))
  368.         {
  369.             e_ptrs[i].behavior &= ~MAT_SKIP;
  370.         }
  371.  
  372.     }
  373.  
  374.     /* Note, we do not use "got". Some platforms want it to be a long
  375.        and some want it to be a int. We don't care, so we make it a
  376.        long (see above) so there's enough room, then use a void * so
  377.        the compiler won't complain about an argument we don't even want */
  378.  
  379.     (void) _dos_write (stream, (char far *) e_ptrs,
  380.         (USHORT) (num_events * sizeof (BINK_EVENT)), (void *)&got);
  381.  
  382.     (void) close (stream);
  383.  
  384.     (void) utime (temp1, (UTIMBUF *) & times);
  385.  
  386.     return;
  387. }
  388.  
  389. void 
  390. write_stats ()
  391. {
  392.     char temp1[80];
  393.     FILE *f;
  394.  
  395.     (void) strcpy (temp1, BINKpath);
  396.     (void) strcat (temp1, PRDCT_PRFX ".Day");
  397.  
  398.     if ((f = fopen (temp1, write_binary)) == NULL)
  399.     {
  400.         return;
  401.     }
  402.  
  403.     (void) fwrite (&hist, (int) sizeof (HISTORY), 1, f);
  404.  
  405.     (void) fclose (f);
  406.  
  407.     return;
  408. }
  409.  
  410. int 
  411. time_to_next (int skip_bbs)
  412. {
  413.     time_t long_time;
  414.     struct tm *tm;
  415.  
  416.     int cur_day;
  417.     int our_time;
  418.     int i;
  419.     int time_to;
  420.     int guess;
  421.     int nmin;
  422.  
  423.     /* Get the current time into a structure */
  424.  
  425.     (void) time (&long_time);
  426.     tm = localtime (&long_time);
  427.  
  428.     our_time = tm->tm_hour * 60 + tm->tm_min;
  429.  
  430.     next_event = -1;
  431.     cur_day = 1 << tm->tm_wday;
  432.  
  433.     /* A ridiculous number */
  434.     time_to = 3000;
  435.  
  436.     /* Make the month 1-based instead of 0-based */
  437.     tm->tm_mon += 1;
  438.  
  439.     /* Go through the events from top to bottom */
  440.     for (i = 0; i < num_events; i++)
  441.     {
  442.         /* If it is the current event, skip it */
  443.         if (cur_event == i)
  444.             continue;
  445.  
  446.         /* If it is a BBS event, skip it */
  447.         if (skip_bbs && e_ptrs[i].behavior & MAT_BBS)
  448.             continue;
  449.  
  450.         /* If it was already run today, skip it */
  451.         if (e_ptrs[i].last_ran == (char) tm->tm_mday)
  452.             continue;
  453.  
  454.         /* If it doesn't happen today, skip it */
  455.         if (!(e_ptrs[i].days & cur_day))
  456.             continue;
  457.  
  458.         /* If not this day of the month, skip it */
  459.         if ((e_ptrs[i].day) && (e_ptrs[i].day != (char) tm->tm_mday))
  460.             continue;
  461.  
  462.         /* If not this month of the year, skip it */
  463.         if ((e_ptrs[i].month) && (e_ptrs[i].month != (char) tm->tm_mon))
  464.             continue;
  465.  
  466.         /* If it is earlier than now, skip it unless it is forced */
  467.         if (e_ptrs[i].minute <= our_time)
  468.         {
  469.             if (!(e_ptrs[i].behavior & MAT_FORCED))
  470.             {
  471.                 continue;
  472.             }
  473.  
  474.             /* Hmm, found a forced event that has not executed yet */
  475.             /* Give the guy 2 minutes and call it quits */
  476.             guess = 2;
  477.         }
  478.         else
  479.         {
  480.             /* Calculate how far it is from now */
  481.             guess = e_ptrs[i].minute - our_time;
  482.         }
  483.  
  484.         /* If less than closest so far, keep it */
  485.         if (time_to > guess)
  486.         {
  487.             time_to = guess;
  488.             next_event = i;
  489.         }
  490.     }
  491.  
  492.     /* If we still have nothing, then do it again, starting at midnight */
  493.     if (time_to >= 1441)
  494.     {
  495.         /* Calculate here to midnight */
  496.         nmin = 1440 - our_time;
  497.  
  498.         /* Go to midnight */
  499.         our_time = 0;
  500.  
  501.         /* Go to the next possible day */
  502.         cur_day = (int) (((unsigned) cur_day) << 1);
  503.         if (cur_day > DAY_SATURDAY)
  504.             cur_day = DAY_SUNDAY;
  505.  
  506.         /* Go through the events from top to bottom */
  507.         for (i = 0; i < num_events; i++)
  508.         {
  509.             /* If it is a BBS event, skip it */
  510.             if (skip_bbs && e_ptrs[i].behavior & MAT_BBS)
  511.                 continue;
  512.  
  513.             /* If it doesn't happen today, skip it */
  514.             if (!(e_ptrs[i].days & cur_day))
  515.                 continue;
  516.  
  517.             /* If not this day of the month, skip it */
  518.             if ((e_ptrs[i].day) && (e_ptrs[i].day != (char) tm->tm_mday))
  519.                 continue;
  520.  
  521.             /* If not this month of the year, skip it */
  522.             if ((e_ptrs[i].month) && (e_ptrs[i].month != (char) tm->tm_mon))
  523.                 continue;
  524.  
  525.             /* Calculate how far it is from now */
  526.             guess = e_ptrs[i].minute + nmin;
  527.  
  528.             /* If less than closest so far, keep it */
  529.             if (time_to > guess)
  530.             {
  531.                 time_to = guess;
  532.                 next_event = i;
  533.             }
  534.         }
  535.     }
  536.  
  537.     if (time_to > 1440)
  538.         time_to = 1440;
  539.  
  540.     if (skip_bbs && (time_to < 1))
  541.         time_to = 1;
  542.  
  543.     return (time_to);
  544. }
  545.